package com.milk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.milk.context.BaseContext;
import com.milk.dto.CommonPageQueryDTO;
import com.milk.dto.OrderDTO;
import com.milk.dto.ShoppingCarDTO;
import com.milk.entity.*;
import com.milk.exception.BaseException;
import com.milk.mapper.*;
import com.milk.result.PageResult;
import com.milk.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.milk.vo.CouponVO;
import com.milk.vo.OrderDetailVO;
import com.milk.vo.OrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-27
 */
@Service
@Slf4j
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private UserCouponMapper userCouponMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private MilkteaMapper milkteaMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 用户点击结算
     * @return
     */
    public OrderVO settle() {
        Long userId = BaseContext.getCurrentId();


        //计算购物车所有的奶茶总价
        QueryWrapper<ShoppingCart> qw = new QueryWrapper<>();
        qw.eq("user_id",userId);
        List<ShoppingCart> list = shoppingCartMapper.selectList(qw);

        //购物车没奶茶信息直接报异常
        if (list==null){
            throw new BaseException("购物车为空");
        }

        double total = 0.0;  //总价
        for (ShoppingCart shoppingCart : list) {
            total += shoppingCart.getAmount();
        }

        //查看该用户的优惠卷
        QueryWrapper<UserCoupon> qwUser = new QueryWrapper<>();
        qwUser.eq("user_id",userId);
        qwUser.ge("valid_until", LocalDateTime.now());
        List<UserCoupon> userCoupons = userCouponMapper.selectList(qwUser);

        if (userCoupons == null || userCoupons.isEmpty()){
            return new OrderVO(list,null,0.0,null);
        }
        //获得该用户的所有优惠卷的id
        List<Long> couponIds = userCoupons.stream().map(UserCoupon::getCouponId).collect(Collectors.toList());

        QueryWrapper<Coupon> qw1 = new QueryWrapper<>();
        qw1.in("id",couponIds);
        List<Coupon> coupons = couponMapper.selectList(qw1);
        List<CouponVO> couponVOs = new ArrayList<>();

        //存放用钱最少的优惠卷
        HashMap<String  , CouponVO> map = new HashMap<>();

        //算出来最优惠的优惠卷

        if (coupons!=null && !coupons.isEmpty()){

            double totalMin = 0.0;

            for (int i = 0; i < coupons.size(); i++) {
                CouponVO couponVO = new CouponVO();
                Coupon coupon = coupons.get(i);
                BeanUtils.copyProperties(coupon,couponVO);

                //该优惠卷为满减
                if (coupon.getCouponType() == 0 && total>=coupon.getThreshold()){
                    double amount = coupon.getDiscountAmount();
                    couponVO.setPrice(amount);
                    if (i == 0 || totalMin < amount){
                        totalMin = amount;
                        map.put("min",couponVO);
                    }
                    couponVOs.add(couponVO);
                }
                //该优惠卷为折扣卷
                else if (coupon.getCouponType()==1){
                    double amount = total-total * coupon.getDiscountRate();
                    //保留两位小数
                    BigDecimal bd = new BigDecimal(amount).setScale(2, RoundingMode.HALF_UP);
                    amount = bd.doubleValue();
                    couponVO.setPrice(amount);
                    if (i == 0 || totalMin < amount){
                        totalMin = amount;
                        map.put("min",couponVO);
                    }
                    couponVOs.add(couponVO);
                }



            }
            //把最优惠的卷放到列表的第一个
//            Coupon coupon = coupons.get(0);
//            coupons.set(0,map.get("min"));
//            coupons.remove(map.get("min"));
//            coupons.add(coupon);

            if (couponVOs.isEmpty()){
                return new OrderVO(list,null,0.0,null);
            }
            //把最优惠的卷放到列表的第一个
            CouponVO couponVO = couponVOs.get(0);
            couponVOs.set(0,map.get("min"));
            couponVOs.remove(map.get("min"));
            couponVOs.add(couponVO);

            OrderVO vo = new OrderVO();
            vo.setId(map.get("min").getId());
            vo.setList(couponVOs);
            vo.setMoney(totalMin);
            vo.setShoppingCartList(list);
            return vo;

        }

        return new OrderVO(list,null,0.0,null);

    }

    /**
     * 下单
     * @param dto
     */
    @Transactional
    public Integer placeOrder(OrderDTO dto) {

        Long userId = BaseContext.getCurrentId();
        User user = userMapper.selectById(userId);
        //TODO 调用接口扣钱 支付成功后

        //添加订单表
        Orders orders = new Orders();
        BeanUtils.copyProperties(dto,orders);

        String data = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        Random random = new Random();
        int i = random.nextInt(999);
        orders.setNumber(i+data);
        orders.setStatus(1);
        orders.setUserId(userId);
        orders.setUserName(user.getName());
        orders.setPhone(user.getPhone());
        orders.setOrderTime(LocalDateTime.now());
        orders.setAmount(dto.getAmount());
        //TODO 使用redis根据日期添加
        String key = "waitId";
        Integer waitId = (Integer) redisTemplate.opsForValue().get(key);
        if (waitId!=null){
            orders.setWaitId(waitId+1);
            redisTemplate.opsForValue().set(key,waitId+1);
        }else {
            orders.setWaitId(1);
            redisTemplate.opsForValue().set(key,1);
        }


        ordersMapper.insert(orders);
        if (dto.getMilkTeaId()!=null){
            Milktea milktea = milkteaMapper.selectById(dto.getMilkTeaId());
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orders.getId());
            orderDetail.setName(milktea.getName());
            orderDetail.setImage(milktea.getImage());
            orderDetail.setNumber(dto.getNumber());
            orderDetail.setMilkteaFlavor(dto.getMilkTeaFlavor());
            orderDetail.setAmount(dto.getAmount());
            orderDetailMapper.insert(orderDetail);
        }else {
            QueryWrapper<ShoppingCart> qw = new QueryWrapper<>();
            qw.eq("user_id",userId);
            //添加订单明细
            List<ShoppingCart> shoppingCarts = shoppingCartMapper.selectList(qw);
            for (ShoppingCart shoppingCart : shoppingCarts) {
                OrderDetail orderDetail = new OrderDetail();
                BeanUtils.copyProperties(shoppingCart,orderDetail);
                orderDetail.setId(null);
                log.info("订单id = {}",orders.getId());
                orderDetail.setOrderId(orders.getId());
                orderDetailMapper.insert(orderDetail);
            }

            //删除购物车数据
            shoppingCartMapper.delete(qw);
        }

        //把使用的优惠卷减少
        if (dto.getCouponId() != null){
            QueryWrapper<UserCoupon> qw1 = new QueryWrapper<>();
            qw1.eq("user_id",userId);
            qw1.eq("coupon_id",dto.getCouponId());
            UserCoupon userCoupon = userCouponMapper.selectOne(qw1);
            //userCoupon.setReceivedTime(LocalDateTime.now());
            if (userCoupon == null) {
                throw new BaseException("无此优惠卷");
            }else if (userCoupon.getNumber()==0){
                throw new BaseException("无此优惠卷");
            } else if (userCoupon.getValidUntil().isBefore(LocalDateTime.now())) {
                throw new BaseException("优惠卷已过期");
            } else if (userCoupon.getNumber() == 1) {
                userCouponMapper.delete(qw1);
            } else if (userCoupon.getNumber() > 1) {
                userCoupon.setNumber(userCoupon.getNumber()-1);
                userCouponMapper.updateById(userCoupon);
            }
        }

        //添加积分

        user.setIntegral(user.getIntegral()+ dto.getAmount());
        userMapper.updateById(user);

        return orders.getWaitId();
    }

    /**
     * 查看今日订单
     * @return
     */
    public List<OrderDetailVO> selectTodayOrder() {
        LocalDateTime min = LocalDateTime.now().with(LocalTime.MIN);
        LocalDateTime max = LocalDateTime.now().with(LocalTime.MAX);
        QueryWrapper<Orders> qw = new QueryWrapper<>();
        qw.eq("user_id",BaseContext.getCurrentId());
        qw.between("order_time",min,max);
        qw.orderByDesc("order_time");
        List<Orders> list = ordersMapper.selectList(qw);
        List<OrderDetailVO> voList = new ArrayList<>();
        for (Orders orders : list) {
            OrderDetailVO orderDetailVO = new OrderDetailVO();
            BeanUtils.copyProperties(orders,orderDetailVO);
            QueryWrapper<OrderDetail> qw1 = new QueryWrapper<>();
            qw1.eq("order_id",orders.getId());
            List<OrderDetail> orderDetails = orderDetailMapper.selectList(qw1);
            orderDetailVO.setOrderDetailList(orderDetails);
            voList.add(orderDetailVO);
        }
        return voList;
    }

    /**
     * 查看历史订单
     * @return
     */
    public List<OrderDetailVO> selectHistory() {
        LocalDateTime min = LocalDateTime.now().with(LocalTime.MIN);
        QueryWrapper<Orders> qw = new QueryWrapper<>();
        qw.eq("user_id",BaseContext.getCurrentId());
        qw.lt("order_time",min);
        qw.orderByDesc("order_time");
        List<Orders> list = ordersMapper.selectList(qw);
        List<OrderDetailVO> voList = new ArrayList<>();
        for (Orders orders : list) {
            OrderDetailVO orderDetailVO = new OrderDetailVO();
            BeanUtils.copyProperties(orders,orderDetailVO);
            QueryWrapper<OrderDetail> qw1 = new QueryWrapper<>();
            qw1.eq("order_id",orders.getId());
            List<OrderDetail> orderDetails = orderDetailMapper.selectList(qw1);
            orderDetailVO.setOrderDetailList(orderDetails);
            voList.add(orderDetailVO);
        }
        return voList;
    }

    /**
     * 根据订单ID查询订单明细
     * @param id
     * @return
     */
    @Override
    public OrderDetailVO selectByOrderId(Long id) {
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        Orders orders = ordersMapper.selectById(id);
        BeanUtils.copyProperties(orders,orderDetailVO);

        QueryWrapper<OrderDetail> qw = new QueryWrapper<>();
        qw.eq("order_id",id);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(qw);
        orderDetailVO.setOrderDetailList(orderDetails);
        return orderDetailVO;
    }

    /**
     * 直接点击购买
     * @param dto
     * @return
     */
    public OrderVO buyOne(ShoppingCarDTO dto) {
        Long userId = BaseContext.getCurrentId();
        Milktea milktea = milkteaMapper.selectById(dto.getMilkTeaId());

        double total = 0.0; //总价
        if (dto.getCup() == 1){
            total = milktea.getPriceMin()* dto.getNumber();
        }else if (dto.getCup() == 2){
            total = milktea.getPriceMedium() * dto.getNumber();
        }else if (dto.getCup() == 3){
            total = milktea.getPriceMax() * dto.getNumber();
        }

        List<ShoppingCart> list = new ArrayList<>();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setImage(milktea.getImage());
        shoppingCart.setNumber(dto.getNumber());
        shoppingCart.setAmount(total);
        shoppingCart.setName(milktea.getName());
        shoppingCart.setMilkteaFlavor(dto.getMilkTeaFlavor());
        shoppingCart.setMilkteaId(dto.getMilkTeaId());

        //查看该用户的优惠卷
        QueryWrapper<UserCoupon> qwUser = new QueryWrapper<>();
        qwUser.eq("user_id",userId);
        qwUser.ge("valid_until", LocalDateTime.now());
        List<UserCoupon> userCoupons = userCouponMapper.selectList(qwUser);

        if (userCoupons == null || userCoupons.isEmpty()){
            return new OrderVO(list,null,0.0,null);
        }
        //获得该用户的所有优惠卷的id
        List<Long> couponIds = userCoupons.stream().map(UserCoupon::getCouponId).collect(Collectors.toList());

        QueryWrapper<Coupon> qw1 = new QueryWrapper<>();
        qw1.in("id",couponIds);
        List<Coupon> coupons = couponMapper.selectList(qw1);
        List<CouponVO> couponVOs = new ArrayList<>();

        //存放用钱最少的优惠卷
        HashMap<String  , CouponVO> map = new HashMap<>();

        //算出来最优惠的优惠卷

        if (coupons!=null && !coupons.isEmpty()){

            double totalMin = 0.0;

            for (int i = 0; i < coupons.size(); i++) {
                CouponVO couponVO = new CouponVO();
                Coupon coupon = coupons.get(i);
                BeanUtils.copyProperties(coupon,couponVO);

                //该优惠卷为满减
                if (coupon.getCouponType() == 0 && total>=coupon.getThreshold()){
                    double amount = coupon.getDiscountAmount();
                    couponVO.setPrice(amount);
                    if (i == 0 || totalMin < amount){
                        totalMin = amount;
                        map.put("min",couponVO);
                    }
                    couponVOs.add(couponVO);
                }
                //该优惠卷为折扣卷
                else if (coupon.getCouponType()==1){
                    double amount = total-total * coupon.getDiscountRate();
                    //保留两位小数
                    BigDecimal bd = new BigDecimal(amount).setScale(2, RoundingMode.HALF_UP);
                    amount = bd.doubleValue();
                    couponVO.setPrice(amount);
                    if (i == 0 || totalMin < amount){
                        totalMin = amount;
                        map.put("min",couponVO);
                    }
                    couponVOs.add(couponVO);
                }



            }

            if (couponVOs.isEmpty()){
                return new OrderVO(list,null,0.0,null);
            }
            //把最优惠的卷放到列表的第一个
            CouponVO couponVO = couponVOs.get(0);
            couponVOs.set(0,map.get("min"));
            couponVOs.remove(map.get("min"));
            couponVOs.add(couponVO);

            OrderVO vo = new OrderVO();
            vo.setId(map.get("min").getId());
            vo.setList(couponVOs);
            vo.setMoney(totalMin);
            vo.setShoppingCartList(list);
            return vo;

        }

        return new OrderVO(list,null,0.0,null);
    }

    /**
     * 分页查询
     * @param dto
     * @return
     */
    public PageResult pageQuery(CommonPageQueryDTO dto) {
        if (dto.getStatus()==0){
            dto.setStatus(null);
        }
        PageHelper.startPage(dto.getPage(),dto.getPageSize());

        Page<Orders> page = ordersMapper.pageQuery(dto);
        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 修改订单状态
     * @param orders
     */
    public void upddateStatus(Orders orders) {
        ordersMapper.updateById(orders);
    }

    /**
     * 查看正在制作的订单数量
     * @return
     */
    public Long selectMaking() {
        QueryWrapper<Orders> qw = new QueryWrapper<>();
        qw.eq("status",0);
        return ordersMapper.selectCount(qw);
    }
}
